<?php
/*
 * @Author: your name
 * @Date: 2020-11-06 15:11:11
 * @LastEditTime: 2021-01-04 18:07:47
 * @LastEditors: Please set LastEditors
 * @Description: 内网ip管理
 * @FilePath: /special/application/adminapiv3/service/asset_manage/address/IntranetIpService.php
 */
namespace app\adminapiv3\service\asset_manage\address;

use app\adminapiv3\service\BaseService;
use app\common\exception\CustomException;
use think\Db;

class IntranetIpService extends BaseService
{
    /**
     * @name: 网络ip列表
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2020-11-06 15:12:20
     */
    public function list ($input)
    {
        $db = Db::name('assest_intranet_ip')->where('address_id', $input['address_id']);
        if(!empty($input['ip']));
        {
            $db->whereLike('ip_s', '%'.$input['ip'].'%');
        }

        $return = $db->paginate()->toArray();
        if(empty($return['data']))
        {
            return $return;
        }
        
        $return['data'] = array_map(function ($v){
            if ($v['ip_s'] == $v['ip_e'])
            {
                $v['ip'] = $v['ip_s'];
            }
            else
            {
                $v['ip'] = $v['ip_s'] . '-'. $v['ip_e'];
            }
            unset($v['ip_s'], $v['ip_e']);

            return $v;
        }, $return['data']);
        
        return $return;
    }

    /**
     * @name: 添加
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2020-11-06 17:40:57
     */
    public function add ($input)
    {
        $input_ip_a = explode(',', $input['ip']);
        $insertData = [];
        foreach ($input_ip_a as $ip)
        {
            $ip_a = explode('-', $ip);
            if(count($ip_a) == 1)
            {
                $ip_a[1] = $ip_a[0];
            }
            $ip_int_s = ip2long($ip_a[0]);
            $ip_int_e = ip2long($ip_a[1]);
            $this->checkExist($input['address_id'], $ip_int_s, $ip_int_e);
            $insertData[] = [
                'ip_s' => $ip_a[0],
                'ip_e' => $ip_a[1],
                'ip_s_int' => $ip_int_s,
                'ip_e_int' => $ip_int_e,
                'address_id' => $input['address_id'],
            ];
        }

        Db::name('assest_intranet_ip')->insertAll($insertData);
    }

    /**
     * @name: 修改
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2020-11-06 17:40:57
     */
    public function modify ($input)
    {
        if (!Db::name('assest_intranet_ip')->where('id', $input['id'])->count())
        {
            throw new CustomException('未找到该内网ip', 422);
        }
        $ip_a = explode('-', $input['ip']);
        unset($input['ip']);
        if(count($ip_a) == 1)
        {
            $ip_a[1] = $ip_a[0];
        }
        $ip_int_s = ip2long($ip_a[0]);
        $ip_int_e = ip2long($ip_a[1]);

        $this->checkExist($input['address_id'], $ip_int_s, $ip_int_e);

        $input['ip_s'] = $ip_a[0];
        $input['ip_e'] = $ip_a[1];
        $input['ip_s_int'] = $ip_int_s;
        $input['ip_e_int'] = $ip_int_e;
        
        Db::name('assest_intranet_ip')->where('id', $input['id'])->update($input);
    }

    /**
     * @name: 删除
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2020-11-06 17:40:57
     */
    public function delete ($id_s)
    {
        if (!Db::name('assest_intranet_ip')->whereIn('id', $id_s)->count())
        {
            throw new CustomException('未找到指定的内网ip', 422);
        }

        Db::name('assest_intranet_ip')->whereIn('id', $id_s)->delete();
    }

    /**
     * @name: 检测ip是否重复
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2021-01-04 17:57:45
     */
    private function checkExist (int $address_id, int $ip_int_s, int $ip_int_e)
    {
        $count = Db::name('assest_intranet_ip')
        ->where(function ($query) use ($address_id, $ip_int_s){
            $query->where([
                ['address_id', '=', $address_id],
                ['ip_s_int', '<=', $ip_int_s],
                ['ip_e_int', '>=', $ip_int_s],
            ]);
        })->whereOr(function ($query) use ($address_id, $ip_int_e){
            $query->where([
                ['address_id', '=', $address_id],
                ['ip_s_int', '<=', $ip_int_e],
                ['ip_e_int', '>=', $ip_int_e],
            ]);
        })
        ->count();
        if ($count)
        {
            if ($ip_int_s == $ip_int_e)
            {
                throw new CustomException('上传的内网ip地址已存在，请勿重复添加', 422);
            }
            else
            {
                throw new CustomException('上传的内网ip段与已存在ip段存在应用范围重合，请勿重复添加', 422);
            }
            
        }
    }
}